/**
 * @file uart.c
 * @author your name (you@domain.com)
 * @brief
 * @version 0.1
 * @date 2023-07-24
 *
 * @copyright Copyright (c) 2023
 *
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <FreeRTOS.h>
#include <queue.h>
#include <timers.h>
#include <task.h>
#include "bflb_uart.h"
#include "bflb_gpio.h"
#include "cmd_uart.h"
#include "log.h"
#include "si4432.h"
#define GBD_TAG "UART"

static void uart_init(void);

static struct bflb_device_s *uart1;
extern xQueueHandle rf_queue;
static bool hasData = false;
static volatile uint8_t *uart_buff;

void cmd_uart_task(void *arg)
{
    uart_init();
    // uint8_t tx_data[4] = {0xAA, 0x00, 0x00, 0xFF};.
    LOG_I("cmd_uart_task \r\n");
    uart_buff = pvPortMalloc(1024);
    int len = 0;
    while (1) {
        if (bflb_uart_rxavailable(uart1)) {
            LOG_I("rto \r\n");
            len = 0;
            memset(uart_buff, 0, 1024);
            while (bflb_uart_rxavailable(uart1)) {
                if (len > 1024) {
                    len = 0;
                }
                uart_buff[len] = bflb_uart_getchar(uart1);
                if (uart_buff[0] != 0xAA) {
                    len = 0;
                } else {
                    len++;
                }
            }

            printf("uart recv:");
            for (int j = 0; j < len; j++) {
                printf("0x%02X ", uart_buff[j]);
            }
            printf("\r\n");

            // LOG_I("tx ret: %d\r\n", bflb_uart_put(uart1, tx_data, 4));
            if (uart_buff[0] == 0xAA) {
                // bflb_uart_putchar(uart1, 0x00);
                xQueueSend(rf_queue, uart_buff, portMAX_DELAY);
            }
            LOG_I("xQueueSend \r\n");
        }
        bflb_mtimer_delay_ms(100);
    }
}

static void uart_isr(int irq, void *arg)
{
    uint32_t intstatus = bflb_uart_get_intstatus(uart1);
    if (hasData) {
        bflb_uart_int_clear(uart1, UART_INTCLR_RTO);
        LOG_I("uart int clear \r\n");
    } else {
        if (intstatus & UART_INTSTS_RTO) {
            uart_buff = pvPortMalloc(1024);
            memset(uart_buff, 0, 1024);
            LOG_I("rto \r\n");
            int len = 0;
            while (bflb_uart_rxavailable(uart1)) {
                if (len > 1024) {
                    break;
                }
                uart_buff[len] = bflb_uart_getchar(uart1);
                if (uart_buff[0] != 0xAA) {
                    len = 0;
                } else {
                    len++;
                }
            }

            printf("uart recv:");
            for (int j = 0; j < len; j++) {
                printf("0x%02X ", uart_buff[j]);
            }
            printf("\r\n");
            hasData = true;
            bflb_uart_int_clear(uart1, UART_INTCLR_RTO);
            LOG_I("uart int clear \r\n");
        }
    }
}

/**
 * @brief
 *
*/
static void uart_init(void)
{
    struct bflb_device_s *gpio;

    struct bflb_uart_config_s cfg = {
        .baudrate = 230400,
        .data_bits = UART_DATA_BITS_8,
        .stop_bits = UART_STOP_BITS_1,
        .parity = UART_PARITY_NONE,
        .flow_ctrl = 0,
        .tx_fifo_threshold = 5,
        .rx_fifo_threshold = 5,
    };

    gpio = bflb_device_get_by_name("gpio");
    uart1 = bflb_device_get_by_name("uart1");

    bflb_gpio_uart_init(gpio, GPIO_PIN_25, GPIO_UART_FUNC_UART1_TX);
    bflb_gpio_uart_init(gpio, GPIO_PIN_26, GPIO_UART_FUNC_UART1_RX);

    bflb_uart_init(uart1, &cfg);

    bflb_uart_txint_mask(uart1, true);
    bflb_uart_rxint_mask(uart1, true);
    // bflb_uart_rxint_mask(uart1, false);
    // bflb_irq_attach(uart1->irq_num, uart_isr, NULL);
    // bflb_irq_enable(uart1->irq_num);
}